﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using WebMobie.Models;
using WebMobie.Models.Entities;
using WebMobie.Modules.Query;

namespace WebMobie.Controllers
{
    public class ProductsController : ApiController
    {
	    static readonly WebMobileContext db = new WebMobileContext();
	    //api/products
	    public IEnumerable<Product> GetAllProducts()
	    {
		    return db.Products;
	    }
	    //api/products/1
	    public ViewProductModel GetProduct(int id)
	    {
		var result = new ViewProductModel();
		var  product = (from item in db.GetAllProduct() where item.ProductId == id  select item).FirstOrDefault();

		if (product != null)
		{
			var promotion = (from item in db.Promotions where item.Product.ProductId == id select item).FirstOrDefault();
			var detail = (from item in db.Details where item.Product.ProductId == id select item).FirstOrDefault();
			result.Product = product;
			result.Promotion = promotion;
			result.Detail = detail;
			
		}

		if (result == null)
		{
			throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
		}
		return result;
	    }
	    //  api/products?brand=apple
	    public IEnumerable<Product> GetProductsByBrand(string brand)
	    {
		    return db.Products.Where(
			p => p.Brand == brand && p.Block == false).ToList();
	    }

	    // api/product    json
		[Authorize(Roles = "Sale")]
	    public HttpResponseMessage PostProduct(Product product)
	    {
		    if (ModelState.IsValid)
		    {
			    product.IsDelete = false;
			    // check modify Role
			    db.Products.Add(product);
			    try
			    {
				    db.SaveChanges();
			    }
			    catch (DbUpdateConcurrencyException)
			    {
				    return Request.CreateResponse(HttpStatusCode.NotFound);
			    }

			    return Request.CreateResponse(HttpStatusCode.OK, product);
		    }
		    else
		    {
			    return Request.CreateResponse(HttpStatusCode.BadRequest);
		    }
	    }

		[Authorize(Roles = "Sale")]
	    [System.Web.Http.HttpPut]
	    public HttpResponseMessage PutData(Product product)
	    {
		    if (ModelState.IsValid)
		    {
			    // check modify Role
			    Product prevProduct = db.Products.Find(product.ProductId);
			    if (prevProduct == null)
				    return Request.CreateResponse(HttpStatusCode.NotFound);
			    db.Entry(prevProduct).State = EntityState.Detached;
			    db.Entry(product).State = EntityState.Modified;
			    try
			    {
				    db.SaveChanges();
			    }
			    catch (DbUpdateConcurrencyException)
			    {
				    return Request.CreateResponse(HttpStatusCode.NotFound);
			    }

			    return Request.CreateResponse(HttpStatusCode.OK, product);
		    }
		    else
		    {
			    return Request.CreateResponse(HttpStatusCode.BadRequest);
		    }
	    }
	    // PUT api/User/5
		[Authorize(Roles = "Sale")]
	    [System.Web.Http.HttpPut]
	    public HttpResponseMessage PutProductData(Product product)
	    {
		    if (ModelState.IsValid)
		    {
			    // check modify Role
			    Product prevProduct = db.Products.Find(product.ProductId);
			    if (prevProduct == null  )
				    return Request.CreateResponse(HttpStatusCode.NotFound);
			    db.Entry(prevProduct).State = EntityState.Detached;
			    db.Entry(product).State = EntityState.Modified;
			    try
			    {
				    db.SaveChanges();
			    }
			    catch (DbUpdateConcurrencyException)
			    {
				    return Request.CreateResponse(HttpStatusCode.NotFound);
			    }

			    return Request.CreateResponse(HttpStatusCode.OK, product);
		    }
		    else
		    {
			    return Request.CreateResponse(HttpStatusCode.BadRequest);
		    }
	    }

			[Authorize(Roles = "Sale")]
	    public HttpResponseMessage PutProduct(List<Product> product)
	    {
		    return Request.CreateResponse(HttpStatusCode.BadRequest);
	    }


	    //===========================================================================================================
	    //	===============================	PROMOTION	================================================ 
	    //=========================================================================================================== 
	    // api/product    json
		[Authorize(Roles = "Sale")]
	    public HttpResponseMessage PostPromotion(Promotion promotion)
	    {
		    if (ModelState.IsValid)
		    {
			    if (promotion.Product.ProductId <= 0)
			    {
				    return Request.CreateResponse(HttpStatusCode.NotFound, "Nhập sản phẩm trước"); 
			    }
			    //find correct product 
			    var  product = (from item in db.GetAllProduct() where item.ProductId == promotion.Product.ProductId select item).FirstOrDefault();
			    if( product == null )
			    {
				    return Request.CreateResponse(HttpStatusCode.NotFound, "Không tồn tại sản phẩm có mã " + promotion.Product.ProductId); 
			    }
			    //find prev Promotion
			    Promotion prevPromotion = (from item in db.Promotions where item.Product.ProductId == promotion.Product.ProductId select item).FirstOrDefault();
			    if (prevPromotion == null)
			    {//add
				    //fix bug Foreign keys in Entity Framework not updating correctly
				    promotion.Product = product;
				    db.Promotions.Add(promotion); 
			    }
			    else //edit
			    {
				    // fix bug duplicate object in context manager
				    prevPromotion.Content = promotion.Content;
				    db.Entry(prevPromotion).State = EntityState.Modified;  
			    }
			    try
			    {
				    db.SaveChanges();
			    }
			    catch (DbUpdateConcurrencyException)
			    {
				    return Request.CreateResponse(HttpStatusCode.NotFound);
			    }  


			    return Request.CreateResponse(HttpStatusCode.OK, promotion);
		    }
		    else
		    {
			    return Request.CreateResponse(HttpStatusCode.BadRequest);
		    }
	    }
	    //===========================================================================================================
	    //	===============================	DETAIL	================================================ 
	    //=========================================================================================================== 
	    // api/product    json
	    // 
			[Authorize(Roles = "Sale")]
	    public HttpResponseMessage PostDetail(Detail detail)
	    {
		    if (ModelState.IsValid)
		    {
			    if (detail.Product.ProductId <= 0)
			    {
				    return Request.CreateResponse(HttpStatusCode.NotFound, "Nhập sản phẩm trước");
			    }
			    //find correct product 
			    var product = (from item in db.GetAllProduct() where item.ProductId == detail.Product.ProductId select item).FirstOrDefault();
			    if (product == null)
			    {
				    return Request.CreateResponse(HttpStatusCode.NotFound, "Không tồn tại sản phẩm có mã " + detail.Product.ProductId);
			    }
			    //find prev Promotion
			    Detail prevdetail = (from item in db.Details where item.Product.ProductId == detail.Product.ProductId select item).FirstOrDefault();
			    if (prevdetail == null)
			    {//add
				    //fix bug Foreign keys in Entity Framework not updating correctly
				    detail.Product = product;
				    db.Details.Add(detail);
			    }
			    else //edit
			    {
				    prevdetail.Content = detail.Content;
				    db.Entry(prevdetail).State = EntityState.Modified;
			    }
			    try
			    {
				    db.SaveChanges();
			    }
			    catch (DbUpdateConcurrencyException)
			    {
				    return Request.CreateResponse(HttpStatusCode.NotFound);
			    }


			    return Request.CreateResponse(HttpStatusCode.OK, detail);
		    }
		    else
		    {
			    return Request.CreateResponse(HttpStatusCode.BadRequest);
		    }
	    }

	    //===========================================================================================================
	    //	===============================	DETAIL	================================================ 
	    //=========================================================================================================== 
	    //=========================================================================================================== 
	    public ShoppingCartViewModel GetShoppingCart()
	    {
		    var cart = ShoppingCart.GetCart(db);

		    // Set up our ViewModel
		    var viewModel = new ShoppingCartViewModel
		    {
			    CartItems = cart.GetCartItems(),
			    CartTotal = cart.GetTotal()
		    };
		    return viewModel;
	    }

	    public HttpResponseMessage PostShopping(int id)
	    {
		    // Retrieve the album from the database
		    var addProduct = db.Products
			.Single(product => product.ProductId == id);

		    if (addProduct != null)
		    {
				// Add it to the shopping cart
				var cart = ShoppingCart.GetCart(db);

				cart.AddToCart(addProduct);

				return Request.CreateResponse(HttpStatusCode.OK);
		    }
			return Request.CreateResponse(HttpStatusCode.BadRequest);
	    }

	    public HttpResponseMessage DeleteCart(int id)
	    {
		    // get the shopping cart
		    var cart = ShoppingCart.GetCart(db);
		    if (cart != null)
		    {
			    if (cart.RemoveFromCart(id) == true)
				    return Request.CreateResponse(HttpStatusCode.OK);
		    }
		    return Request.CreateResponse(HttpStatusCode.BadRequest);
	    }

	    public HttpResponseMessage PutCarts(UpdateCarts updateCarts)
	    {
		    int i = 0;
		    // get the shopping cart
		    var cart = ShoppingCart.GetCart(db);
		    if (cart != null)
		    {

			    if (updateCarts.IsInvalid())
			    {
				    for (i = 0; i < updateCarts.IDs.Length; i++)
				    {
					    cart.UpdateCart(updateCarts.IDs[i], updateCarts.Counts[i]);
				    }
				    return Request.CreateResponse(HttpStatusCode.OK);
			    }
			
			    
		    }
		    return Request.CreateResponse(HttpStatusCode.BadRequest);
	    }

	    public int GetSummary()
	    {
		 var cart = ShoppingCart.GetCart(db);
		    if (cart != null)
		    {
			    return cart.GetCountDistinct();
		    }
		    return 0;

	    }

	    public HttpResponseMessage PostCheckOut( CheckOut checkOut)
	    {
		    if (ModelState.IsValid)
		    {
			    var cart = ShoppingCart.GetCart(db);
			    if (cart != null)
			    {
					if( string.IsNullOrEmpty(checkOut.address))
						return Request.CreateResponse(HttpStatusCode.BadRequest);
					if (string.IsNullOrEmpty(checkOut.phone))
						return Request.CreateResponse(HttpStatusCode.BadRequest);
					if (string.IsNullOrEmpty(checkOut.name))
						return Request.CreateResponse(HttpStatusCode.BadRequest);

				    ShippingInfo ship = null;
				    if (checkOut.receiveAt != 1)
				    {
					    ship = new ShippingInfo
					    {
						    Address = checkOut.address,
						    Phone = checkOut.phone
					    };

				    }

				    var order = new Order
				    {
					CustomerName = checkOut.name,
					CustomerPhone = checkOut.phone,
					Status = 1,
					DateCreated = DateTime.Now,
					ShippingInfo = ship
				    };
				    db.Orders.Add(order);
				    cart.CreateOrder(order);


			    }

			    return Request.CreateResponse(HttpStatusCode.OK);
		    }
		    else
		    {
			    return Request.CreateResponse(HttpStatusCode.BadRequest);
		    }
	    }

			[Authorize(Roles = "Sale")]
	    public IEnumerable<Order> GetFreeOrder()
	    {
		return db.Orders.Where(
		order => order.Status  == OrderState.Free).ToList();
	    }

			[Authorize(Roles = "Sale")]
			public IEnumerable<Order> GetOrder()
			{
				return db.Orders.ToList();
			}

			[Authorize(Roles = "Sale")]
			public IEnumerable<Order> GetOrderSearch(string id)
			{
				return db.Orders.Where(
				order => order.CustomerPhone == id || order.CustomerName.Contains(id)).ToList();
			}

			[Authorize(Roles = "Sale")]
	    public IEnumerable<Order> GetCheckedOrder()
	    {
		    return db.Orders.Where(
		    order => order.Status == OrderState.Checked).ToList();
	    }

			[Authorize(Roles = "Sale")]
	    public HttpResponseMessage DeleteOrder(int id)
	    {
		    IEnumerable<OrderDetail> orderDetails = db.OrderDetails.Where(o => o.Order.Id == id);
		    foreach (OrderDetail orderDetail in orderDetails)
		    {
			    db.OrderDetails.Remove(orderDetail);
		    }
			var order = db.Orders.Where(or => or.Id == id).FirstOrDefault();
		    db.Orders.Remove(order);
		    db.SaveChanges();
		    return Request.CreateResponse(HttpStatusCode.OK);
	    }

			[Authorize(Roles = "Sale")]
	    public HttpResponseMessage PutConfirmOrder(int orderid, int shiperid)
	    {
		    UserInfo userinfo = new UserInfo();
		    User  user = userinfo.GetUserSession();
			Order order = db.Orders.Where(or => or.Id == orderid).FirstOrDefault();
		   
		    if (order != null && user != null)
		    {
			    order.SellerId = user.UserID;
			    if (order.ShippingInfo != null)
			    {
					User shiper = db.Users.Where(u => u.UserID == shiperid).FirstOrDefault();
				    order.ShippingInfo.User = shiper;
			    }
			    order.Status = OrderState.Checked;
			    db.SaveChanges();
			    return Request.CreateResponse(HttpStatusCode.OK);
		    }
		    return Request.CreateResponse(HttpStatusCode.BadRequest);
	    }

			[Authorize(Roles = "Sale")]
	    public HttpResponseMessage PutFinishOrder(int id)
	    {
			Order order = db.Orders.Where(or => or.Id == id).FirstOrDefault();
		    if (order != null)
		    {
			    order.Status = OrderState.Finished;
			    db.SaveChanges();
			    return Request.CreateResponse(HttpStatusCode.OK);
		    }
		    return Request.CreateResponse(HttpStatusCode.BadRequest);
	    }


	    ///=================== Filter
	    /// 
	    public IEnumerable<Product> GetMobiles()
	    {
		    var products = (from item in db.GetAllProduct() where item.Type == Defines.TYPE_MOBILE && item.Block == false select item);

		    if (products == null)
		    {
			    throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
		    }
		    return products;
	    }

	    public IEnumerable<Product> GetMobilesBrand(string id)
	    {
			var products = (from item in db.GetAllProduct() where item.Type == Defines.TYPE_MOBILE && item.Brand == id && item.Block == false select item);

		    if (products == null)
		    {
			    throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
		    }
		    return products;
	    }

	    public IEnumerable<Product> GetPhuKiens()
	    {
		    var products = (from item in db.GetAllProduct() where item.Type == Defines.TYPE_PHUKIEN && item.Block == false select item);

		    if (products == null)
		    {
			    throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
		    }
		    return products;
	    }

	    public IEnumerable<Product> GetPhuKiensBrand(string id)
	    {
			var products = (from item in db.GetAllProduct() where item.Type == Defines.TYPE_PHUKIEN && item.Brand == id && item.Block == false select item);

		    if (products == null)
		    {
			    throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
		    }
		    return products;
	    }

	    public IEnumerable<Product> GetMobileUsed()
	    {
			var products = (from item in db.GetAllProduct() where item.Type == Defines.TYPE_MOBILE && item.IsUsed == true && item.Block == false select item);

		    if (products == null)
		    {
			    throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
		    }
		    return products;
	    }

	    public IEnumerable<Product> GetTablets()
	    {
			var products = (from item in db.GetAllProduct() where item.Type == Defines.TYPE_TABLET && item.Block == false select item);

		    if (products == null)
		    {
			    throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
		    }
		    return products;
	    }

	    public IEnumerable<Product> GetTabletsBrand(string id)
	    {
			var products = (from item in db.GetAllProduct() where item.Type == Defines.TYPE_TABLET && item.Brand == id && item.Block == false select item);

		    if (products == null)
		    {
			    throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
		    }
		    return products;
	    }

		public IEnumerable<Product> GetSearch(string id)
		{
			var products = (from item in db.GetAllProduct() where (item.Name.Contains(id) || item.Brand.Contains(id)) && item.Block == false select item);

			if (products == null)
			{
				throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
			}
			return products;
		}

	    public string[] GetColor()
	    {
			string[] colors = (from item in db.ThamSos where item.TType == Defines.THAMSO_TYPE_COLOR select item.Value).ToArray();
		    return colors;
	    }

		public string[] GetBrand()
		{
			string[] colors = (from item in db.ThamSos where item.TType == Defines.THAMSO_TYPE_BRAND select item.Value).ToArray();
			return colors;
		}

		public HttpResponseMessage GetPutColor(string id)
		{
			ThamSo thamSo = db.ThamSos.Where(ts => ts.VType  == Defines.THAMSO_TYPE_COLOR && ts.Value == id).FirstOrDefault();
			if (thamSo == null)
			{
				thamSo = new ThamSo { Id = Guid.NewGuid(), VType = 1, TType = Defines.THAMSO_TYPE_COLOR, Value = id };
				db.ThamSos.Add(thamSo);
				db.SaveChanges();
				return Request.CreateResponse(HttpStatusCode.OK);
			}
			return Request.CreateResponse(HttpStatusCode.BadRequest);
		}

		public HttpResponseMessage GetPutBrand(string id)
		{
			ThamSo thamSo = db.ThamSos.Where(ts => ts.VType == Defines.THAMSO_TYPE_BRAND && ts.Value == id).FirstOrDefault();
			if (thamSo == null)
			{
				thamSo = new ThamSo { Id = Guid.NewGuid(), VType = 1, TType = Defines.THAMSO_TYPE_BRAND, Value = id };
				db.ThamSos.Add(thamSo);
				db.SaveChanges();
				return Request.CreateResponse(HttpStatusCode.OK);
			}
			return Request.CreateResponse(HttpStatusCode.BadRequest);
		}

		public IEnumerable<Product> GetPromotion()
		{
			var products = (from item in db.GetAllProduct() where item.Promotion == true && item.Block == false select item);

			if (products == null)
			{
				throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
			}
			return products;
		}

		public IEnumerable<Product> GetCommingSoon()
		{
			var products = (from item in db.GetAllProduct() where item.CommingSoon == true && item.Block == false select item);

			if (products == null)
			{
				throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
			}
			return products;
		}


    }
}
